﻿#region

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using Newtonsoft.Json;
using VinhSon.Intranet.Bussiness;
using VinhSon.Intranet.Models;
using VinhSon.Intranet.Models.ExtJs;

#endregion

namespace VinhSon.Intranet.Controllers
{
    public class BaseController : Controller
    {
        protected readonly UnitOfWork UnitOfWork = new UnitOfWork();

        protected int GetUserId()
        {
            int i;
            int.TryParse(Session["UserId"] + "",
                         out i);
            return i;
        }

        protected bool CheckUser(int userId,
                                 out User curUser)
        {
            User user = UnitOfWork.UserRepository.Select(c => c.Id == userId && c.Inactive == false)
                                  .FirstOrDefault();
            if(user != null)
            {
                curUser = user;
                return true;
            }
            curUser = null;
            return false;
        }

        #region Format result for display on grid

        protected string FormatResult<T>(IQueryable<T> query,
                                         Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
                                         int start,
                                         int limit,
                                         string sort,
                                         IEnumerable<string> sortEx)
        {
            int total = query.Count();

            if(start < 0
               || start > total)
                start = 0;
            IQueryable<T> q1 = query.OrderBy(sort,
                                             orderBy,
                                             sortEx);
            if(limit > 0)
                q1 = q1.Skip(start)
                       .Take(limit);

            return FormatResult(total,
                                q1);
        }

        protected string FormatResult<T, TK>(IQueryable<T> query,
                                             Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
                                             int start,
                                             int limit,
                                             string sort,
                                             IEnumerable<string> sortEx,
                                             Func<IEnumerable<T>, IEnumerable<TK>> func)
        {
            int total = query.Count();

            if(start < 0
               || start > total)
                start = 0;
            IQueryable<T> q1 = query.OrderBy(sort,
                                             orderBy,
                                             sortEx);
            if(limit > 0)
                q1 = q1.Skip(start)
                       .Take(limit);

            return FormatResult(total,
                                func.Invoke(q1.ToList()));
        }

        private string FormatResult<T>(int total,
                                       IEnumerable<T> q1)
        {
            StringBuilder stringBuilder = new StringBuilder();
            JsonWriter writer = new JsonTextWriter(new StringWriter(stringBuilder));
            writer.Formatting = Formatting.None;

            writer.WriteStartObject();
            writer.WritePropertyName("total");
            writer.WriteValue(total);
            writer.WritePropertyName("data");
            writer.WriteStartArray();

            Type type = typeof (T);
            foreach (T item in q1)
            {
                writer.WriteStartObject();
                foreach (PropertyInfo propertyInfo in type.GetProperties())
                {
                    writer.WritePropertyName(propertyInfo.Name);
                    writer.WriteValue(propertyInfo.GetValue(item,
                                                            null));
                }
                writer.WriteEndObject();
            }

            writer.WriteEndArray();
            writer.WriteEndObject();
            return stringBuilder.ToString();
        }

        #endregion
    }
}
